﻿using Snowflake.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml;

namespace WeChatV3Pay.Core
{
    public class WeChatStringHelper
    {
        /// <summary>
        /// 签名
        /// </summary>
        /// <param name="httpMethod">Http请求类型</param>
        /// <param name="url">请求地址</param>
        /// <param name="body">请求体</param>
        /// <param name="privateKey">签名私钥</param>
        /// <param name="serialNo">证书编号</param>
        /// <param name="merchantId">商户号</param>
        /// <returns></returns>
        public static string Sign(string httpMethod, string url, string body, string privateKey, string serialNo, string merchantId)
        {
            var worker = new IdWorker(1, 1);
            var noice = worker.NextId();
            var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
            var sourceStr = $"{httpMethod}\n{url}\n{timestamp}\n{noice}\n{body}\n";

            // NOTE： 私钥不包括私钥文件起始的-----BEGIN PRIVATE KEY-----
            //        亦不包括结尾的-----END PRIVATE KEY-----
            var KeyData = Convert.FromBase64String(privateKey);
            var rsa = RSA.Create();
            rsa.ImportPkcs8PrivateKey(KeyData, out _);
            var data = Encoding.UTF8.GetBytes(sourceStr);
            var signature = Convert.ToBase64String(rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
            return $"WECHATPAY2-SHA256-RSA2048 mchid=\"{merchantId}\",nonce_str=\"{noice}\",timestamp=\"{timestamp}\",serial_no=\"{serialNo}\",signature=\"{signature}\"";
        }

        /// <summary>
        /// 获取随机字符串
        /// </summary>
        /// <returns></returns>
        public static string GenerateTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }


        /// <summary>
        /// 生成签名
        /// </summary>
        /// <param name="privateKey"></param>
        /// <param name="appId"></param>
        /// <param name="timeStamp"></param>
        /// <param name="nonceStr"></param>
        /// <param name="package"></param>
        /// <returns></returns>
        public static string MakeSign(string privateKey, string appId, string timeStamp, string nonceStr, string package)
        {
            var sourceStr = $"{appId}\n{timeStamp}\n{nonceStr}\n{package}\n";
            // NOTE： 私钥不包括私钥文件起始的-----BEGIN PRIVATE KEY-----
            //        亦不包括结尾的-----END PRIVATE KEY-----
            var KeyData = Convert.FromBase64String(privateKey);
            var rsa = RSA.Create();
            rsa.ImportPkcs8PrivateKey(KeyData, out _);
            var data = Encoding.UTF8.GetBytes(sourceStr);
            return Convert.ToBase64String(rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
        }
    }
}
